home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
os2
/
remin301.zip
/
REMIN300.ZIP
/
VAR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-10
|
12KB
|
409 lines
/***************************************************************/
/* */
/* VAR.C */
/* */
/* This file contains routines, structures, etc for */
/* user- and system-defined variables. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1991 by David F. Skoll. */
/* */
/***************************************************************/
#include <stdio.h>
#include "config.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include "types.h"
#include "expr.h"
#include "globals.h"
#include "protos.h"
#include "err.h"
#define UPPER(c) ( ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c) )
/* The variable hash table */
#define VAR_HASH_SIZE 64
static Var *VHashTbl[VAR_HASH_SIZE];
/***************************************************************/
/* */
/* HashVal */
/* Given a string, compute the hash value. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int HashVal(const char *str)
#else
int HashVal(str)
char *str;
#endif
{
register int i = 0;
register int j=1;
register int len=0;
while(*str && len < VAR_NAME_LEN) {
i += j * UPPER(*str);
str++;
len++;
j = 3-j;
}
return i;
}
/***************************************************************/
/* */
/* FindVar */
/* Given a string, find the variable whose name is that */
/* string. If create is 1, create the variable. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC Var *FindVar(const char *str, int create)
#else
Var *FindVar(str, create)
char *str;
int create;
#endif
{
register int h;
register Var *v;
register Var *prev;
h = HashVal(str) % VAR_HASH_SIZE;
v = VHashTbl[h];
prev = NULL;
while(v) {
if (StrinEq(str, v->name, VAR_NAME_LEN)) return v;
prev = v;
v = v-> next;
}
if (!create) return v;
/* Create the variable */
v = NEW(Var);
if (!v) return v;
v->next = NULL;
v->v.type = INT_TYPE;
v->v.v.val = 0;
v->preserve = 0;
StrnCpy(v->name, str, VAR_NAME_LEN);
if (prev) prev->next = v; else VHashTbl[h] = v;
return v;
}
/***************************************************************/
/* */
/* DeleteVar */
/* Given a string, find the variable whose name is that */
/* string and delete it. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DeleteVar(const char *str)
#else
int DeleteVar(str)
char *str;
#endif
{
register int h;
register Var *v;
register Var *prev;
h = HashVal(str) % VAR_HASH_SIZE;
v = VHashTbl[h];
prev = NULL;
while(v) {
if (StrinEq(str, v->name, VAR_NAME_LEN)) break;
prev = v;
v = v-> next;
}
if (!v) return E_NOSUCH_VAR;
DestroyValue(&(v->v));
if (prev) prev->next = v->next; else VHashTbl[h] = v->next;
free(v);
return OK;
}
/***************************************************************/
/* */
/* SetVar */
/* */
/* Set the indicate variable to the specified value. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int SetVar(const char *str, Value *val)
#else
int SetVar(str, val)
char *str;
Value *val;
#endif
{
Var *v = FindVar(str, 1);
if (!v) return E_NO_MEM; /* Only way FindVar can fail */
DestroyValue(&(v->v));
v->v = *val;
return OK;
}
/***************************************************************/
/* */
/* GetVarValue */
/* */
/* Get a copy of the value of the variable. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int GetVarValue(const char *str, Value *val, Var *locals)
#else
int GetVarValue(str, val, locals)
char *str;
Value *val;
Var *locals;
#endif
{
Var *v;
/* Try searching local variables first */
v = locals;
while (v) {
if (StrinEq(str, v->name, VAR_NAME_LEN))
return CopyValue(val, &v->v);
v = v->next;
}
v=FindVar(str, 0);
if (!v) {
Eprint("Undefined variable: %s", str);
return E_NOSUCH_VAR;
}
return CopyValue(val, &v->v);
}
/***************************************************************/
/* */
/* DoSet - set a variable. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoSet (Parser *p)
#else
int DoSet (p)
Parser *p;
#endif
{
Value v;
int r;
r = ParseIdentifier(p, TokBuffer);
if (r) return r;
r = EvaluateExpr(p, &v);
if (r) return r;
r = SetVar(TokBuffer, &v);
return r;
}
/***************************************************************/
/* */
/* DoUnset - delete a bunch of variables. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoUnset (Parser *p)
#else
int DoUnset (p)
Parser *p;
#endif
{
int r;
r = ParseToken(p, TokBuffer);
if (r) return r;
if (!*TokBuffer) return E_EOLN;
(void) DeleteVar(TokBuffer); /* Ignore error - nosuchvar */
/* Keep going... */
while(1) {
r = ParseToken(p, TokBuffer);
if (r) return r;
if (!*TokBuffer) return OK;
(void) DeleteVar(TokBuffer);
}
}
/***************************************************************/
/* */
/* DoDump */
/* */
/* Command file command to dump variable table. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoDump(ParsePtr p)
#else
int DoDump(p)
ParsePtr p;
#endif
{
int r;
Var *v;
r = ParseToken(p, TokBuffer);
if (r) return r;
if (!*TokBuffer || *TokBuffer == '#' || *TokBuffer == ';') {
DumpVarTable();
return OK;
}
fprintf(ErrFp, "%*s %s\n\n", VAR_NAME_LEN, "Variable", "Value");
while(1) {
v = FindVar(TokBuffer, 0);
TokBuffer[VAR_NAME_LEN] = 0;
if (!v) fprintf(ErrFp, "%*s *UNDEFINED*\n", VAR_NAME_LEN, TokBuffer);
else {
fprintf(ErrFp, "%*s ", VAR_NAME_LEN, v->name);
PrintValue(&(v->v), ErrFp);
fprintf(ErrFp, "\n");
}
r = ParseToken(p, TokBuffer);
if (r) return r;
if (!*TokBuffer || *TokBuffer == '#' || *TokBuffer == ';') return OK;
}
}
/***************************************************************/
/* */
/* DumpVarTable */
/* */
/* Dump the variable table to stderr. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void DumpVarTable(void)
#else
void DumpVarTable()
#endif
{
register Var *v;
register int i;
fprintf(ErrFp, "%*s %s\n\n", VAR_NAME_LEN, "Variable", "Value");
for (i=0; i<VAR_HASH_SIZE; i++) {
v = VHashTbl[i];
while(v) {
fprintf(ErrFp, "%*s ", VAR_NAME_LEN, v->name);
PrintValue(&(v->v), ErrFp);
fprintf(ErrFp, "\n");
v = v->next;
}
}
}
/***************************************************************/
/* */
/* DestroyVars */
/* */
/* Free all the memory used by variables, but don't delete */
/* preserved variables. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void DestroyVars(void)
#else
void DestroyVars()
#endif
{
int i;
Var *v, *next, *prev;
for (i=0; i<VAR_HASH_SIZE; i++) {
v = VHashTbl[i];
VHashTbl[i] = NULL;
prev = NULL;
while(v) {
if (!v->preserve) {
DestroyValue(&(v->v));
next = v->next;
free(v);
} else {
if (prev) prev->next = v;
else VHashTbl[i] = v;
prev = v;
next = v->next;
v->next = NULL;
}
v = next;
}
}
}
/***************************************************************/
/* */
/* PreserveVar */
/* */
/* Given the name of a variable, "preserve" it. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int PreserveVar(char *name)
#else
int PreserveVar(name)
char *name;
#endif
{
Var *v;
v = FindVar(name, 1);
if (!v) return E_NO_MEM;
v->preserve = 1;
return OK;
}
/***************************************************************/
/* */
/* DoPreserve - delete a bunch of variables. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoPreserve (Parser *p)
#else
int DoPreserve (p)
Parser *p;
#endif
{
int r;
r = ParseToken(p, TokBuffer);
if (r) return r;
if (!*TokBuffer) return E_EOLN;
r = PreserveVar(TokBuffer);
if (r) return r;
/* Keep going... */
while(1) {
r = ParseToken(p, TokBuffer);
if (r) return r;
if (!*TokBuffer) return OK;
r = PreserveVar(TokBuffer);
if (r) return r;
}
}